//
//  RelatedFilesArrayController.m
//  Pennyworth Punch Clock
//
//  Created by Chris Karr on 8/6/08.
//  Copyright 2008 Northwestern University. All rights reserved.
//

#import "RelatedFilesArrayController.h"
#import "DocumentManager.h"
#import "AppDelegate.h"

@implementation RelatedFilesArrayController

@synthesize state;

- (NSString *) commentForPath:(NSString *) path
{
	NSString * scriptString = [NSString stringWithFormat:@"tell application \"Finder\" to return the comment of alias (POSIX file \"%@\" as text)", path];
	NSAppleScript * script = [[NSAppleScript alloc] initWithSource:scriptString];
	NSAppleEventDescriptor * desc = [script executeAndReturnError:nil];
	[script release];
	
	return [desc stringValue];
}

- (void) setComment:(NSString *) comment forPath:(NSString *) path
{
	NSString * scriptString = [NSString stringWithFormat:@"tell application \"Finder\" to set the comment of alias (POSIX file \"%@\" as text) to \"%@\"", path, comment];
	NSAppleScript * script = [[NSAppleScript alloc] initWithSource:scriptString];
	[script executeAndReturnError:nil];
	[script release];
}

- (void) update:(NSNotification *) theNote
{
	[[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateState:) userInfo:nil repeats:NO] retain];
}

- (void) updateState:(NSTimer *) theTimer
{
	[theTimer release];
	
	self.state = [((AppDelegate *) [NSApp delegate]) getActiveState];
	NSMutableString * predicateString = [NSMutableString string];
	
	for (NSString * key in [self.state allKeys])
	{
		NSString * queryString = [NSString stringWithFormat:@"kMDItemFinderComment = '*%@ = %@*'", key, [self.state valueForKey:key], nil];
		
		if ([predicateString length] > 0)
			[predicateString appendString:@" || "];
		
		[predicateString appendString:queryString];
	}
	
	NSTask * searchTask = [[NSTask alloc] init];
	
	NSPipe * stdoutPipe = [NSPipe pipe];
	
	[searchTask setStandardOutput:stdoutPipe];
	[searchTask setLaunchPath:@"/usr/bin/mdfind"];
	[searchTask setArguments:[NSArray arrayWithObject:predicateString]];
	
	NSFileHandle * out = [[stdoutPipe fileHandleForReading] retain];
	
	[searchTask launch];
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(findDone:) 
												 name:NSFileHandleReadToEndOfFileCompletionNotification 
											   object:nil];
	
	[out readToEndOfFileInBackgroundAndNotify];
}

- (IBAction) clearSelectedObjects:(id) sender
{
	for (NSDictionary * item in [self selectedObjects])
	{
		NSString * path = [item valueForKey:PATH];
		
		NSMutableString * comment = [NSMutableString stringWithString:[self commentForPath:path]];
		
		for (NSString * key in [self.state allKeys])
		{
			NSString * tag = [NSString stringWithFormat:@"%@ = %@;", key, [self.state valueForKey:key], nil];
			
			if ([comment rangeOfString:tag].location != NSNotFound)
				[comment replaceOccurrencesOfString:tag withString:@"" options:0 range:NSMakeRange (0, [comment length])];
		}

		[self setComment:comment forPath:path];
	}
	
	[self update:nil];
}

- (IBAction) revealInFinder:(id) sender
{
	NSWorkspace * workspace = [NSWorkspace sharedWorkspace];
	
	for (NSDictionary * item in [self selectedObjects])
	{
		NSString * path = [item valueForKey:PATH];
		
		[workspace selectFile:path inFileViewerRootedAtPath:nil];
	}
}

- (void) awakeFromNib
{
	[[NSDistributedNotificationCenter defaultCenter] addObserver:self 
														selector:@selector(update:) 
															name:PREDICTION_FETCHED 
														  object:nil];
	
	[[NSNotificationCenter defaultCenter] addObserver:self 
											 selector:@selector(update:) 
												 name:PREDICTION_FETCHED 
											   object:nil];
}

- (void) findDone: (NSNotification *) notification
{
	[self willChangeValueForKey:@"arrangedObjects"];
	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:nil];
	
	NSDictionary * userInfo = [notification userInfo];
	
	NSData * importData = [userInfo valueForKey:NSFileHandleNotificationDataItem];

	NSString * results = [[NSString alloc] initWithData:importData encoding:NSUTF8StringEncoding];
	
	[self removeObjects:[self arrangedObjects]];

	for (NSString * path in [results componentsSeparatedByString:@"\n"])
	{
		if (path != nil && ![path isEqual:@""])
		{
			NSString * fileApp = nil;
			NSString * fileType = nil;
			
			if ([[NSWorkspace sharedWorkspace] getInfoForFile:path application:&fileApp type:&fileType])
			{
				NSMutableDictionary * fileDict = [NSMutableDictionary dictionary];
				[fileDict setValue:path forKey:PATH];
				[fileDict setValue:fileApp forKey:APP];
				[fileDict setValue:fileType forKey:TYPE];
				[fileDict setValue:[path lastPathComponent] forKey:NAME];
				
				[self addObject:fileDict];
			}
		}
	}
	
	[results release];
	[self didChangeValueForKey:@"arrangedObjects"];
}

- (BOOL)tableView:(NSTableView *) tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard
{
	return NO;
}

- (NSDragOperation) tableView:(NSTableView *) tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int) row
		proposedDropOperation:(NSTableViewDropOperation) op
{
	NSArray * paths = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType];
	
	for (NSString * path in paths)
	{
		BOOL found = NO;
		
		for (NSDictionary * file in [self arrangedObjects])
		{
			if ([[file valueForKey:PATH] isEqual:path])
				found = YES;
		}
		
		if (!found)
			return NSDragOperationEvery;
	}
	
	return NSDragOperationNone;
}

- (BOOL) tableView:(NSTableView *) tableView acceptDrop:(id <NSDraggingInfo>) info row:(int) row 
	 dropOperation:(NSTableViewDropOperation) operation
{
	NSArray * paths = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType];
	
	for (NSString * path in paths)
	{
		NSString * fileApp = nil;
		NSString * fileType = nil;
		
		if ([[NSWorkspace sharedWorkspace] getInfoForFile:path application:&fileApp type:&fileType])
		{
			NSMutableDictionary * fileDict = [NSMutableDictionary dictionary];
			[fileDict setValue:path forKey:PATH];
			[fileDict setValue:fileApp forKey:APP];
			[fileDict setValue:fileType forKey:TYPE];
			[fileDict setValue:[path lastPathComponent] forKey:NAME];
			
			[self addObject:fileDict];

			NSMutableString * comment = [NSMutableString string];
			NSString * currentComment = [self commentForPath:path];

			if (currentComment != nil)
				[comment appendString:currentComment];

			for (NSString * key in [self.state allKeys])
			{
				for (NSString * value in [self.state valueForKey:key])
				{
					NSString * tag = [NSString stringWithFormat:@"%@ = %@; ", key, value, nil];
				
					if ([comment rangeOfString:tag].location == NSNotFound)
						[comment appendString:tag];
				}
			}
			
			[self setComment:comment forPath:path];
		}
	}
	
	return YES;
}

@end
